const {EnumBehavior, EnumRole, EnumReplenish} = require("./Enum");
module.exports.initDefault = () => {

    Creep.prototype.usedStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getUsedCapacity(sourceType);
    };

    Creep.prototype.freeStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getFreeCapacity(sourceType);
    };

    Creep.prototype.maxStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getCapacity(sourceType);
    };

    Creep.prototype.isFull=function(){
        return this.usedStore() === this.maxStore();
    }

    Creep.prototype.isEmpty=function(){
        return this.freeStore() === this.maxStore();
    }

    Creep.prototype.bestMove = function (to) {
        let color="#fff";
        switch (this.memory.role){
            case EnumRole.Harvest:color="#ffe56d";break;
            case EnumRole.OutHarvest:color="#ffe56d";break;
            case EnumRole.Engineer:color="#3f51b5";break;
            case EnumRole.OutEngineer:color="#3f51b5";break;
        }
        let result = this.moveTo(to, {
            reusePath: 10,
            visualizePathStyle: {
                fill: 'transparent',
                stroke: color,
                lineStyle: 'dashed',
                strokeWidth: .15,
                opacity: .1
            }
        });
        if (result !== 0 && result !== -11 && result !== -4) {
            // 如果路径被阻挡，creep.moveTo 会尝试重新计算路径并移动
            result = this.moveTo(to, {
                reusePath: 5,
                visualizePathStyle: {
                    fill: 'transparent',
                    stroke: 'red',
                    lineStyle: 'dashed',
                    strokeWidth: .15,
                    opacity: .1
                }
            });
        }
        return result;
    }
    function getRoomCostMatrix(roomName) {
        const room = Game.rooms[roomName];
        if (!room) return true; // 房间不可见时返回
        const matrix = new PathFinder.CostMatrix();

        // 可选：标记其他障碍物（如敌方建筑、己方非通行建筑）
        room.find(FIND_STRUCTURES).forEach(build => {
            if(build.structureType !== STRUCTURE_CONTAINER && build.structureType!==STRUCTURE_ROAD &&
                (build.structureType !== STRUCTURE_RAMPART || !build.my)){
                matrix.set(build.pos.x, build.pos.y, 0xFF);
            }
        });
        // 躲避房间中的 creep
        room.find(FIND_CREEPS).forEach(function(creep) {
            matrix.set(creep.pos.x, creep.pos.y, 0xff);
        });

        room.find(FIND_CONSTRUCTION_SITES).forEach(site => {
            matrix.set(site.pos.x, site.pos.y, 0xFF);
        });

        return matrix;
    }
    //序列化
    function serializePath(path) {
        return path.map(pos => ({
            x: pos.x,
            y: pos.y,
            roomName: pos.roomName  // 必须包含房间名！
        }));
    }
    //反序列化
    function deserializePath(storedPath) {
        return JSON.parse(storedPath).map(posData =>
            new RoomPosition(posData.x, posData.y, posData.roomName) // ✅ 重建有效对象
        );
    }
    Creep.prototype.bestOutMove = function (to) {
        let path;
        if(!this.memory.outMovePath){
            let pathItem=PathFinder.search(this.pos,{ pos: to, range: 1 },{
                roomCallback:getRoomCostMatrix,
            })
            if(pathItem){
                path=pathItem.path
                this.memory.outMovePath=JSON.stringify(serializePath(pathItem.path));
            }
        }
        if(this.memory.outMovePath){
            path=deserializePath(this.memory.outMovePath);
            let result = this.moveByPath(path);
            path=path.filter(pathItem=>pathItem.roomName===this.room.name);
            this.room.visual.poly(path,{
                fill: 'transparent',
                stroke: '#fff',
                lineStyle: 'dashed',
                strokeWidth: .15,
                opacity: .1
            })
            if (result !== 0 && result !== -11 && result !== -4) {
                // 如果路径被阻挡，creep.moveTo 会尝试重新计算路径并移动
                let pathItem=PathFinder.search(this.pos,{ pos: to, range: 1 },{
                    roomCallback:getRoomCostMatrix,
                })
                if(pathItem){
                    path=pathItem.path
                    this.memory.outMovePath=JSON.stringify(serializePath(pathItem.path));
                }
                result = this.moveByPath(path);
                path=path.filter(pathItem=>pathItem.roomName===this.room.name);
                this.room.visual.poly(path,{
                    fill: 'transparent',
                    stroke: 'red',
                    lineStyle: 'dashed',
                    strokeWidth: .15,
                    opacity: .1
                })
            }
            return result;
        }
    }


    Creep.prototype.bestAttack = function (to) {
        let state = this.attack(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestAttackController = function (to) {
        let state = this.attackController(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestBuild = function (to) {
        let state = this.build(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestClaimController = function (to) {
        let state = this.claimController(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestDismantle = function (to) {
        let state = this.dismantle(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state
    }

    Creep.prototype.bestHarvest = function (to) {
        let state = this.harvest(to);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestHeal = function (to) {
        let state = this.heal(to);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestPickup = function (to) {
        let state = this.pickup(to)
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestPull = function (to) {
        let state = this.pull(to);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestRangedAttack = function (to) {
        let state = this.rangedAttack(to)
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestRangedHeal = function (to) {
        let state = this.rangedHeal(to)
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestRangedMassAttack = function (to) {
        let state = this.rangedMassAttack()
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestRepair = function (to) {
        let state = this.repair(to);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestReserveController = function (to) {
        let state = this.reserveController(to);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestSignController = function (to, sign) {
        let state = this.signController(to, sign);
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestTrans = function (to, resourceType = RESOURCE_ENERGY) {
        let state = this.transfer(to, resourceType);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestUpController = function (to) {
        let isNearList = this.pos.findInRange([to],2);
        let state;
        if(isNearList.length>0){
            state=this.upgradeController(to);
        }else{
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bestWithdraw = function (to, resourceType = RESOURCE_ENERGY) {
        let state = this.withdraw(to, resourceType);
        
        if (state === ERR_NOT_IN_RANGE) {
            this.bestMove(to);
        }
        return state;
    }

    Creep.prototype.bindBehavior = function (behavior, behaviorId) {
        this.memory.behavior = behavior;
        this.memory.behaviorId = behaviorId;
        this.memory.isBehavior=true;
    }

    Creep.prototype.bindReplenish=function (replenish, replenishId) {
        this.memory.replenish = replenish;
        this.memory.replenishId = replenishId;
    }
    Creep.prototype.finishBehavior=function (){
        this.memory.behavior=EnumBehavior.Free;
        this.memory.behaviorId=undefined;
        this.memory.isBehavior=false;
        this.memory.replenish=EnumReplenish.Free;
        this.memory.replenishId=undefined;
    }
    Creep.prototype.finishReplenishId=function (){
        this.memory.replenish=EnumReplenish.Free;
        this.memory.replenishId=undefined;
    }


    Structure.prototype.usedStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getUsedCapacity(sourceType);
    };

    Structure.prototype.freeStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getFreeCapacity(sourceType);
    };

    Structure.prototype.maxStore = function (sourceType = RESOURCE_ENERGY) {
        return this.store.getCapacity(sourceType);
    };
}
